home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2007 December / PCWKCD1207B.iso / Blogowanie poza sfera / Flock 1.0 beta / flock-1.0RC3.en-US.win32.exe / flock / components / flockSearchAPIFlock.js < prev    next >
Text File  |  2007-10-18  |  11KB  |  338 lines

  1. //
  2. // BEGIN FLOCK GPL
  3. // 
  4. // Copyright Flock Inc. 2005-2007
  5. // http://flock.com
  6. // 
  7. // This file may be used under the terms of of the
  8. // GNU General Public License Version 2 or later (the "GPL"),
  9. // http://www.gnu.org/licenses/gpl.html
  10. // 
  11. // Software distributed under the License is distributed on an "AS IS" basis,
  12. // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  13. // for the specific language governing rights and limitations under the
  14. // License.
  15. // 
  16. // END FLOCK GPL
  17. //
  18.  
  19. const CLASS_ID                = Components.ID("{C711A35C-8949-4D01-9676-47E71F1A78F4}");
  20. const CLASS_NAME              = "Flock Results Search Module";
  21. const CONTRACT_ID             = "@flock.com/flock-search-flock;1";
  22. const flockISearchService     = Components.interfaces.flockISearchService;
  23.  
  24. const FLOCK_NS = "http://flock.com/rdf#";
  25. const NC_NS = "http://home.netscape.com/NC-rdf#";
  26.  
  27. const RDFCU = Components.classes["@mozilla.org/rdf/container-utils;1"].getService(Components.interfaces.nsIRDFContainerUtils);
  28. const RDFS = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
  29.  
  30. function flockSearchAPIFlock()
  31. {
  32.   this._favService = Components.classes["@mozilla.org/rdf/datasource;1?name=flock-favorites"].getService(Components.interfaces.nsIRDFDataSource);
  33.   this._logger = Components.classes["@flock.com/logger;1"].createInstance(Components.interfaces.flockILogger);
  34.   this._logger.init("search");
  35.   var sbs = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
  36.   var bundle = sbs.createBundle("chrome://flock/locale/search/search.properties");
  37.   this.serviceName = bundle.GetStringFromName("flock.search.api.flock");
  38. };
  39.  
  40. flockSearchAPIFlock.prototype = {
  41.  
  42.   _searchListener: null,
  43.   _maxResults: null,
  44.   _searchesOutstanding: null,
  45.   _resultsBookmarks: null,
  46.   _resultsHistory: null,
  47.   _currentQuery: null,
  48.   RDFS: null,
  49.   shortName: "flock",
  50.   icon: "rdf:http://flock.com/rdf#icon",
  51.   ref: "urn:flock:search:results",
  52.   mDS: null,
  53.   fullResultsUrl: "flock://search/?query=",
  54.  
  55.   search: function(aQuery, aNumResults, aListener, aDatasource)
  56.   {
  57.     this._searchListener = aListener;
  58.     this._maxResults = aNumResults;
  59.     
  60.     this._currentQuery = aQuery;
  61.     
  62.     // get references to the services we use
  63.     var searchService = Components.classes["@flock.com/lucene/flockLucene;1"].getService(Components.interfaces.flockILucene);
  64.     this.RDFS = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
  65.     var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
  66.     
  67.     // save a ref to the ds passed in
  68.     this.mDS = aDatasource;
  69.     
  70.     var normalizedQuery = this.normalizeQuery(aQuery);
  71.     
  72.     this._logger.debug("query: \"" + aQuery + "\" => \"" + normalizedQuery + "\"");
  73.     
  74.     var showHistory = prefService.getBoolPref("flock.search.flyout.showHistory") && prefService.getBoolPref("flock.service.indexer.indexWebHistory");
  75.     
  76.     // clear results
  77.     this._resultsBookmarks = [];
  78.     this._resultsHistory = [];
  79.     
  80.     // start the searchs
  81.     if (showHistory) {
  82.       this._searchesOutstanding = 2;
  83.       searchService.search(normalizedQuery, "bookmark", this._maxResults, this);
  84.       searchService.search(normalizedQuery, "history", this._maxResults, this);
  85.     } else {
  86.       this._searchesOutstanding = 1;
  87.       searchService.search(normalizedQuery, "bookmark", this._maxResults, this);
  88.     }
  89.   },
  90.   
  91.   normalizeQuery: function(input)
  92.   {
  93.     var output;
  94.     var in_quotes = false;
  95.  
  96.     // strip leading spaces
  97.     while (input.length && input[0]==" ") {
  98.       // chop off the first character
  99.       input = input.substr(1);
  100.     }
  101.  
  102.     // Convert to lowercase for the wildcard search
  103.     input = input.toLowerCase();
  104.   
  105.     // add leading plus
  106.     output = "+";
  107.     while (input.length) {
  108.       if (input[0] == "\"") {
  109.         if (in_quotes) {
  110.           in_quotes = false;
  111.         } else {
  112.           in_quotes = true;
  113.           // FIXME: remove spaces from the start of quoted strings
  114.         }
  115.       }
  116.  
  117.       // escape special chars
  118.       if ("&|!(){}[]^~*?:\\".indexOf(input[0]) >= 0) {
  119.         output = output + "\\";
  120.       }
  121.  
  122.       output = output + input[0];
  123.  
  124.       if (!in_quotes && input[0] == " " && input.length > 1) {
  125.           // put a plus before every word
  126.           output = output + "+";
  127.       }
  128.  
  129.       input = input.substr(1);
  130.     }
  131.  
  132.     // remove trailing spaces
  133.     var removed_spaces = false;
  134.     while (output.length > 0 && output[output.length - 1] == " ") {
  135.       output = output.substr(0, output.length - 1);
  136.       removed_spaces = true;
  137.     }
  138.  
  139.     // if we're in a quoted string we should close that
  140.     if (in_quotes) {
  141.       output = output + "\"";
  142.     }
  143.   
  144.     // if theres an incomplete word
  145.     if ((!removed_spaces) && (output[output.length - 1] != "\"")) {
  146.       // search for partial matches
  147.       output = output + "*";
  148.     }
  149.  
  150.     return output;
  151.   },
  152.   
  153.   // flockILuceneListener
  154.   onSearchComplete: function(aNumResults, aResults) {
  155.     this._logger.debug("onSearchComplete: hits: " + aNumResults);
  156.  
  157.     if (aNumResults > 0) {
  158.       while (aResults.hasMoreElements()) {
  159.         var result = aResults.getNext();
  160.         result.QueryInterface(Components.interfaces.flockILuceneResult);
  161.         this._logger.debug("foundResults: " + result.type + " " + result.URI);
  162.  
  163.         switch (result.type) {
  164.           case "bookmark":
  165.             this._resultsBookmarks.push([result.URL, result.title]);
  166.             break;
  167.           case "history":
  168.             this._resultsHistory.push([result.URL, result.title]);
  169.             break;
  170.         }
  171.       }
  172.     }
  173.     
  174.     this._searchesOutstanding--;
  175.     
  176.     if (this._searchesOutstanding == 0) {
  177.       this._returnResults();
  178.     }
  179.   },
  180.   
  181.   _returnResults: function()
  182.   {
  183.     this._logger.debug("_returnResults");
  184.     
  185.     var resultSet = this.mDS;
  186.     var resultSetRoot = this.RDFS.GetResource("urn:flock:search:results");
  187.     var rootContainer = RDFCU.MakeSeq(resultSet, resultSetRoot);
  188.     
  189.     var c;
  190.     var urlHash = {};
  191.     var url;
  192.     var title;
  193.     var favicon;
  194.     var result;
  195.     var resultCount = 0;
  196.     
  197.     // return bookmark results
  198.     for (c = 0; c < this._resultsBookmarks.length && resultCount < this._maxResults; c++) {
  199.       url = this._resultsBookmarks[c][0];
  200.       title = this._resultsBookmarks[c][1];
  201.       favicon = "chrome://browser/skin/flock/search/documentIcon16.png";
  202.       infoicon = "chrome://flock/skin/common/star16.png";
  203.       
  204.       // skip duplicate bookmarks (online bookmarks)
  205.       if (urlHash[url] == true) {
  206.         continue;
  207.       }
  208.  
  209.       urlHash[url] = true;
  210.       
  211.       result = this.RDFS.GetAnonymousResource();
  212.  
  213.       rootContainer.AppendElement(result);
  214.     
  215.       resultSet.Assert(result, this.RDFS.GetResource("http://home.netscape.com/NC-rdf#URL"), this.RDFS.GetLiteral(url), true);
  216.       resultSet.Assert(result, this.RDFS.GetResource("http://home.netscape.com/NC-rdf#Name"), this.RDFS.GetLiteral(title), true);
  217.       resultSet.Assert(result, this.RDFS.GetResource("http://home.netscape.com/NC-rdf#favicon"), this.RDFS.GetLiteral(favicon), true);
  218.       resultSet.Assert(result, this.RDFS.GetResource(FLOCK_NS + "infoicon"), this.RDFS.GetLiteral(infoicon), true);
  219.       
  220.       resultCount++;
  221.     }
  222.     
  223.     // fill in history results
  224.     for (c = 0; c < this._resultsHistory.length && resultCount < this._maxResults; c++) {
  225.       url = this._resultsHistory[c][0];
  226.       title = this._resultsHistory[c][1];
  227.       favicon = "chrome://browser/skin/flock/search/documentIcon16.png";
  228.       
  229.       // skip history results that have already been returned as bookmarks
  230.       if (urlHash[url] == true) {
  231.         continue;
  232.       }
  233.       
  234.       result = this.RDFS.GetAnonymousResource();
  235.  
  236.       rootContainer.AppendElement(result);
  237.     
  238.       resultSet.Assert(result, this.RDFS.GetResource("http://home.netscape.com/NC-rdf#URL"), this.RDFS.GetLiteral(url), true);
  239.       resultSet.Assert(result, this.RDFS.GetResource("http://home.netscape.com/NC-rdf#Name"), this.RDFS.GetLiteral(title), true);
  240.       resultSet.Assert(result, this.RDFS.GetResource("http://home.netscape.com/NC-rdf#favicon"), this.RDFS.GetLiteral(favicon), true);
  241.       
  242.       resultCount++;
  243.     }
  244.   
  245.     this._searchListener.foundResults(resultCount, resultSet, this.shortName, this._currentQuery);
  246.     // JMC - Trying to fix leak of this listener
  247.     this._searchListener = null;
  248.   },  
  249.   
  250.   // nsIClassInfo
  251.   getInterfaces: function(aCount)
  252.   {
  253.     var interfaces = [Components.interfaces.flockISearchService, Components.interfaces.nsIClassInfo, Components.interfaces.flockILuceneListener];
  254.     aCount.value = interfaces.length;
  255.     return interfaces;
  256.   },
  257.  
  258.   // nsIClassInfo
  259.   getHelperForLanguage: function(aLanguage)
  260.   {
  261.     return null;
  262.   },
  263.  
  264.   // nsIClassInfo
  265.   contractID: CONTRACT_ID,
  266.  
  267.   // nsIClassInfo
  268.   classDescription: CLASS_NAME,
  269.  
  270.   // nsIClassInfo
  271.   classID: CLASS_ID,
  272.  
  273.   // nsIClassInfo
  274.   implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
  275.  
  276.   // nsIClassInfo
  277.   flags: Components.interfaces.nsIClassInfo.SINGLETON,
  278.   
  279.   // nsISupports
  280.   QueryInterface: function(aIID)
  281.   {
  282.     if (!aIID.equals(Components.interfaces.nsISupports) && !aIID.equals(Components.interfaces.flockISearchService) && !aIID.equals(Components.interfaces.nsIClassInfo) && !aIID.equals(Components.interfaces.flockILuceneListener))
  283.       throw Components.results.NS_ERROR_NO_INTERFACE;
  284.     return this;
  285.   }
  286.  
  287. };
  288.  
  289. /******************************************************************************
  290.  * XPCOM Functions for construction and registration
  291.  ******************************************************************************/
  292. var Module = {
  293.   _firstTime: true,
  294.   registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)
  295.   {
  296.     if (this._firstTime) {
  297.       this._firstTime = false;
  298.       throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
  299.     }
  300.     aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  301.     aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME, CONTRACT_ID, aFileSpec, aLocation, aType);
  302.     
  303.     // register search provider
  304.     var catmgr = Components.classes["@mozilla.org/categorymanager;1"]
  305.       .getService(Components.interfaces.nsICategoryManager);
  306.     catmgr.addCategoryEntry("flockISearchService", "flock", CONTRACT_ID, true, true);
  307.   },
  308.  
  309.   unregisterSelf: function(aCompMgr, aLocation, aType)
  310.   {
  311.     aCompMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  312.     aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);        
  313.   },
  314.   
  315.   getClassObject: function(aCompMgr, aCID, aIID)
  316.   {
  317.     if (!aIID.equals(Components.interfaces.nsIFactory))
  318.       throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  319.     if (aCID.equals(CLASS_ID))
  320.       return Factory;
  321.     throw Components.results.NS_ERROR_NO_INTERFACE;
  322.   },
  323.  
  324.   canUnload: function(aCompMgr) { return true; }
  325. };
  326.  
  327. var Factory = {
  328.   createInstance: function(aOuter, aIID)
  329.   {
  330.     if (aOuter != null)
  331.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  332.     return (new flockSearchAPIFlock()).QueryInterface(aIID);
  333.   }
  334. };
  335.  
  336. function NSGetModule(aCompMgr, aFileSpec) { return Module; }
  337.  
  338.